<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/6/13
 * Time: 11:29
 */

namespace iBrand\Shop\Server\Controllers\V2;


use iBrand\Component\Goods\Models\Goods;
use iBrand\Component\Goods\Models\GoodsProduct;
use iBrand\Component\Goods\Models\GoodsSpecRelation;
use iBrand\Component\Goods\Models\SpecsValue;
use iBrand\Component\Goods\Repositories\GoodsProductRepository;
use iBrand\Component\Purchase\Models\Purchase;
use iBrand\Component\Purchase\Repositories\PurchaseItemRepository;
use iBrand\Component\Purchase\Repositories\PurchaseRepository;
use iBrand\Component\Purchase\Repositories\StockRecordRepository;
use iBrand\Shop\Core\Repositories\O2oGoodsProductsRepository;
use iBrand\Shop\Core\Repositories\O2oGoodsRepository;
use iBrand\Shop\Core\Service\WarehouseService;
use iBrand\Shop\Server\Resources\PurchaseItemResource;
use iBrand\Shop\Server\Resources\PurchaseResource;
use iBrand\Shop\Server\Service\WarehouseProductService;
use Illuminate\Support\Facades\DB;

class PurchaseController extends \iBrand\Common\Controllers\Controller
{
    protected $o2oGoodsProductRepository;
    protected $productRepository;
    protected $purchaseRepository;
    protected $warehouseService;
    protected $o2oGoodsRepository;
    protected $warehouseProductService;
    protected $stockRecordRepository;
    protected $purchaseItemRepository;

    public function __construct(O2oGoodsProductsRepository $o2oGoodsProductsRepository,
                                GoodsProductRepository $goodsProductRepository,
                                PurchaseRepository $purchaseRepository,
                                WarehouseService $warehouseService,
                                O2oGoodsRepository $o2oGoodsRepository,
                                WarehouseProductService $warehouseProductService,
                                StockRecordRepository $stockRecordRepository,
                                PurchaseItemRepository $purchaseItemRepository)
    {
        $this->o2oGoodsProductRepository = $o2oGoodsProductsRepository;
        $this->productRepository = $goodsProductRepository;
        $this->purchaseRepository = $purchaseRepository;
        $this->warehouseService = $warehouseService;
        $this->o2oGoodsRepository = $o2oGoodsRepository;
        $this->warehouseProductService = $warehouseProductService;
        $this->stockRecordRepository = $stockRecordRepository;
        $this->purchaseItemRepository = $purchaseItemRepository;
    }

    /**
     * 采购入库或库存调拨：扫码或输入货号搜索获取product信息
     * @return \Illuminate\Http\Response
     */
    public function getProductData()
    {
        $clerk = auth('clerk')->user();
        $sku = request('sku');
        $type = request('type');

        if ($type == 'scan') {
            $product = $this->warehouseProductService->getProductDataBySku($sku);
            if (!$product) return $this->failed('商品不存在');

            $currentStock = $this->stockRecordRepository->getCurrentStock($clerk->shop_id, $product->id, GoodsProduct::class);
            $product->currentStock = $currentStock;
        } else {
            $product = $this->warehouseProductService->getProductDataByCode($sku);

            if (!$product->count()) return $this->failed('商品不存在');

            foreach ($product as $item) {
                $currentStock = $this->stockRecordRepository->getCurrentStock($clerk->shop_id, $item->id, GoodsProduct::class);
                $item->currentStock = $currentStock;
            }
        }

        return $this->success($product);
    }


    /**
     * 采购/采购退货
     * @return \Illuminate\Http\Response|mixed
     */
    public function purchase()
    {
        $clerk = auth('clerk')->user();

        $type = request('type');
        $remark = request('remark');
        $goods = request('goods');
        $shop_id = $clerk->shop_id;

        if (count($goods) == 0) {
            return $this->failed('请提交商品信息');
        }

        $prefix = 'JT';

        $purchaseData = [
            'shop_id' => $shop_id,
            'code' => $prefix . date('YmdHis') . mt_rand(10000000, 99999999),
            'clerk_id' => $clerk->id,
            'type' => $type,
            'remark' => $remark,
            'status' => Purchase::STATUS_DEFAULT
        ];

        try {
            DB::beginTransaction();

            $purchase = $this->purchaseRepository->create($purchaseData);

            $quantity = 0;
            $total = 0;

            foreach ($goods as $good) {
                if ($good['currentSku']) {
                    $product = $this->productRepository->getProductBySku($good['currentSku']);
                    $item_id = $product->id;
                    $item_type = GoodsProduct::class;
                } else {
                    $item_id = $good['goods_id'];
                    $item_type = Goods::class;
                }

                $good['discount'] = 100;
                $good['truePrice'] = $good['price'];
                $good['trueAmount'] = $good['price'] * $good['quantity'];

                $this->warehouseService->addPurchaseItem($purchase->id, $good, $item_id, $item_type);

                $this->warehouseService->addStockRecord($shop_id, $purchase->id, $good, $type, $item_id, $item_type);

                $o2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $good['goods_id'], 'shop_id' => $shop_id])->first();
                if (!$o2oGoods) {
                    $o2oGoods = $this->o2oGoodsRepository->create([
                        'goods_id' => $good['goods_id'],
                        'shop_id' => $shop_id,
                        'price' => $good['price'],
                    ]);
                }

                $o2oGoodsId = $o2oGoods->id;

                $this->warehouseService->addO2oGoodsProduct($shop_id, $o2oGoodsId, $good['goods_id'], $good['quantity'], 'Purchase', $type, $item_id);

                if ($type == Purchase::TYPE_REJECT) {
                    $o2oGoods->reduceStock($good['quantity']);
                } else {
                    $o2oGoods->restoreStock($good['quantity']);
                }

                $quantity += $good['quantity'];
                $total += $good['quantity'] * $good['price'];
            }

            $purchase->quantity = $quantity;
            $purchase->total = $total;
            $purchase->save();

            DB::commit();

            return $this->success();
        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception->getTraceAsString());

            return $this->failed('提交失败');
        }
    }

    /**
     * 获取采购、退货记录
     * @return mixed
     */
    public function getPurchaseData()
    {
        $type = request('type');  //PURCHASE REJECT
        $clerk = auth('clerk')->user();
        $shop_id = $clerk->shop_id;
        $limit = request('limit') ? request('limit') : 20;
        $list = $this->purchaseRepository->scopeQuery(function ($query) use ($shop_id, $type) {
            return $query->where('shop_id', $shop_id)->where('type', $type);
        })->with('clerk')->orderBy('created_at', 'desc')->paginate($limit);

        return $this->paginator($list, PurchaseResource::class);
    }


    /**
     * 获取明细
     * @return mixed
     */
    public function getPurchaseItem()
    {
        $id = request('id');
        $limit = request('limit') ? request('limit') : 20;
        $list = $this->purchaseItemRepository->scopeQuery(function ($query) use ($id) {
            return $query->where('purchase_id', $id);
        })->paginate($limit);

        return $this->paginator($list, PurchaseItemResource::class);
    }

}